package com.example.controller.pc;


import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.annotation.Log;
import com.example.common.result.Result;
import com.example.entity.dto.pc.DeviceLoadDetailPerDayDto;
import com.example.entity.dto.pc.DeviceLoadStatusDto;
import com.example.entity.dto.pc.ResourceListDto;
import com.example.entity.hz.MOCTA;
import com.example.entity.mysql.Resource;
import com.example.entity.mysql.Resourcegroup;
import com.example.entity.mysql.Workresource;
import com.example.entity.vo.DeviceProductLineListVo;
import com.example.entity.vo.pc.LoadDateVo;
import com.example.entity.vo.pc.MoctyPlus;
import com.example.entity.vo.pc.ResourceListVo;
import com.example.entity.vo.pc.ResourceLoadListVo;
import com.example.entity.yifei.Cmsmd;
import com.example.enums.MOCStatusEnum;
import com.example.enums.MachineStatusEnum;
import com.example.mapper.MoctaMapper;
import com.example.mapper.MoctyMapper;
import com.example.mapper.SFCTEMapper;
import com.example.mapper.pc.ProductprocessresourceMapper;
import com.example.mapper.pc.ResourceMapper;
import com.example.mapper.pc.ResourcegroupMapper;
import com.example.service.CmsmdService;
import com.example.service.pc.FactoryService;
import com.example.service.pc.ResourceService;
import com.example.service.pc.ResourcegroupService;
import com.example.service.pc.WorkresourceService;
import com.example.untils.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author LiangPandeng
 * @since 2024-05-19
 */
@RestController
@Api(tags = "资源")
@RequestMapping("/api/resource")
public class ResourceController {
    @Autowired
    private MoctyMapper moctyMapper;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private FactoryService factoryService;
    @Autowired
    private SFCTEMapper sfcteMapper;
    @Autowired
    private MoctaMapper moctaMapper;
    @Autowired
    private WorkresourceService workresourceService;
    @Autowired
    private ResourcegroupMapper resourcegroupMapper;
    @Autowired
    private ResourcegroupService resourceGroupService;
    @Autowired
    private CmsmdService cmsmdService;
    @Autowired
    private ResourceMapper resourceMapper;
    @Autowired
    private ProductprocessresourceMapper productprocessresourceMapper;

    /**
     * 设备名称  设备编号  资源组编号不能为空
     * @param resource
     * @return
     */
    @Log("添加设备资源")
    @ApiOperation("添加设备资源")
    @PostMapping("addResource")
    @DSTransactional
    public Result addResource(@RequestBody Resource resource) {
        if(StringUtils.isEmpty(resource.getDeviceid()) || StringUtils.isEmpty(resource.getDevicename())) {
            return Result.error("资源编号或资源名称不能为空");
        }
        if(resource.getResourceGroupId() == null) {
            return Result.error("资源组ID不能为空");
        }
        if(StringUtils.isEmpty(resource.getLvTwoLastMaintenanceDay()) || StringUtils.isEmpty(resource.getLvThreeLastMaintenanceDay())) {
            return Result.error("最后二级保养日或最后三级保养日不能为空");
        }
//        Integer count = resourcegroupMapper.selectCount(new LambdaQueryWrapper<Resourcegroup>()
//                .eq(Resourcegroup::getResourceGroupId, resource.getResourceGroupId()));
//        if(count == null || count == 0) {
//            return Result.error("资源组ID不存在");
//        }
        Integer count = resourceService.count(new LambdaQueryWrapper<Resource>()
                .eq(Resource::getDeviceid, resource.getDeviceid()));
        if(count != null && count > 0) {
            return Result.error("资源编号已被使用");
        }
        // 添加Resourcegroup数据
        Resourcegroup resourcegroup = new Resourcegroup();
        resourcegroup.setType("F");
        resourcegroup.setResourceGroupNO(resource.getDeviceid());
        resourcegroup.setResourceGroupName(resource.getDevicename());
        resourcegroup.setResourceGroupParentId(resource.getResourceGroupId());
        resourceGroupService.save(resourcegroup);
        // 添加resource数据
        resource.setResourceid(null);
        resource.setResourceType(1);
        resource.setResourceGroupIdIsF(resourcegroup.getResourceGroupId());
        boolean b = resourceService.save(resource);
        if(b) return Result.success("添加资源成功");
        else return Result.success("添加资源失败");
    }

    @ApiOperation("机器查询时能选择的状态")
    @PostMapping("macCanSelStatus")
    public Result macCanSelStatus() {
        List<String> list = MachineStatusEnum.getAllStatuses();
        return Result.success(list);
    }

    @ApiOperation("机器编辑时能修改的状态")
    @PostMapping("macCanUpdateStatus")
    public Result<List<String>> canUpdateStatus() {
        List<String> res = new ArrayList<>();
        res.add(MachineStatusEnum.XianZhi.getValue());
        res.add(MachineStatusEnum.BaoFei.getValue());
        return Result.success(res);
    }

    @Log("编辑设备资源")
    @ApiOperation("编辑设备资源")
    @PostMapping("editResource")
    @DSTransactional
    public Result editResource(@RequestBody Resource resource) {
        if(StringUtils.isEmpty(resource.getDeviceid()) || StringUtils.isEmpty(resource.getDevicename())) {
            return Result.error("资源编号和资源名称不能为空");
        }
        if(resource.getResourceGroupId() == null || resource.getResourceid() == null) {
            return Result.error("资源组ID和资源ID不能为空");
        }
        if(StringUtils.isEmpty(resource.getLvTwoLastMaintenanceDay()) || StringUtils.isEmpty(resource.getLvThreeLastMaintenanceDay())) {
            return Result.error("最后二级保养日或最后三级保养日不能为空");
        }
        Resource one = resourceService.getOne(new LambdaQueryWrapper<Resource>()
                .eq(Resource::getDeviceid, resource.getDeviceid()));
        if(one != null && !one.getResourceid().equals(resource.getResourceid())) {
            return Result.error("设备编号已被使用");
        }
        one = resourceService.getOne(new LambdaQueryWrapper<Resource>()
                .eq(Resource::getResourceid, resource.getResourceid()));
        // 添加Resourcegroup数据
        Resourcegroup resourcegroup = new Resourcegroup();
        resourcegroup.setResourceGroupId(one.getResourceGroupIdIsF());
        resourcegroup.setResourceGroupNO(resource.getDeviceid());
        resourcegroup.setResourceGroupName(resource.getDevicename());
        resourcegroup.setResourceGroupParentId(resource.getResourceGroupId());
        resourceGroupService.updateById(resourcegroup);
        // TODO
        boolean b = resourceService.updateById(resource);
        if(b) return Result.success("修改资源成功");
        else return Result.success("修改资源失败");
    }

    @ApiOperation("设备资源列表")
    @PostMapping("resourceList")
    public Result<PageInfo<List<ResourceListVo>>> resourceList(@RequestBody ResourceListDto dto) {
        List<Cmsmd> cmsmdList = cmsmdService.list();
        Map<String, String> map = new HashMap<>();
        for(Cmsmd cmsmd : cmsmdList) {
            map.put(cmsmd.getMd001().trim(), cmsmd.getMd002().trim());
        }

        // 现在正在使用的工单

        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        List<ResourceListVo> list = resourceService.resourceList(dto);
        for(ResourceListVo t : list) {
            t.setWorkCenterName(map.get(t.getWorkCenter()));
        }
        PageInfo<List<ResourceListVo>> pageInfo = new PageInfo(list);
        return Result.success(pageInfo);
    }

    @ApiOperation("设备|生产线列表")
    @PostMapping("deviceProductLineList")
    public Result<List<ResourceListVo>> deviceProductLineList(@RequestBody ResourceListDto dto) {

        List<String> statusList = new ArrayList<>();
        statusList.add(MOCStatusEnum.DaiShouJian.getValue());  statusList.add(MOCStatusEnum.ShouJianZhong.getValue());
        statusList.add(MOCStatusEnum.DaiJinZhan.getValue());  statusList.add(MOCStatusEnum.ShengChanZhong.getValue());
        statusList.add(MOCStatusEnum.DaiKaiJi.getValue());  statusList.add(MOCStatusEnum.ZanTing.getValue());
        statusList.add(MOCStatusEnum.DaiShangLiaoQueRen.getValue()); statusList.add(MOCStatusEnum.DaiMuJuQueRen.getValue());
        List<MoctyPlus> moctyList = moctyMapper.moctyOnQueueListByMocStatusMocta(statusList);
        Set<String> macSet = new HashSet<>();
        for(MoctyPlus t : moctyList) {
            macSet.add(t.getTy009());
        }
        List<String> macList = new ArrayList<>();
        for(String t : macSet) macList.add(t);

        if(macList.size() == 0) {
            macList.add("XXXXXXXX");
        }
        // 找到所有在做的机器
        List<ResourceListVo> list = resourceService.deviceProductLineList(dto, macList);
        List<Cmsmd> cmsmdList = cmsmdService.list();
        Map<String, String> cmsmdMap = new HashMap<>();
        for(Cmsmd cmsmd : cmsmdList) {
            cmsmdMap.put(cmsmd.getMd001().trim(), cmsmd.getMd002().trim());
        }
        for(ResourceListVo t : list) {
            if(StringUtils.isNotEmpty(t.getWorkCenter())) {
                t.setWorkCenterName(cmsmdMap.get(t.getWorkCenter().trim()));
            }
            if(StringUtils.isNotEmpty(t.getMoctyudf05())) {
                // 查看目前已报工数量
//                BigDecimal bgNums = sfcteMapper.getAlreadyBGmocty(t.getMoctyudf05());
//                t.setBgNums(bgNums);
                MoctyPlus mocty = moctyMapper.getMoctyPlus(t.getMoctyudf05());
                if(mocty != null) {
                    MOCTA mocta = moctaMapper.selectOne(new LambdaQueryWrapper<MOCTA>()
                            .eq(MOCTA::getTA001, mocty.getTy001())
                            .eq(MOCTA::getTA002, mocty.getTy002()));
                    t.setMoctyNums(new BigDecimal(mocty.getTy004()));
                    t.setMacOnTime(mocty.getUdf07());
                    t.setProductionNums(mocta.getTA017());
                    t.setTy001(mocty.getTy001());
                    t.setTy002(mocty.getTy002());
                    t.setOrderSingle(mocty.getOrderSingle());
                    t.setOrderNo(mocty.getOrderNo());
                    t.setOrderSerialId(mocty.getOrderSerialId());
                    t.setCustomSimpleName(mocty.getCustomSimpleName());
                    t.setSaleOrderNum(mocty.getSaleOrderNum());
                    List<Workresource> workresourceList = workresourceService.list(new LambdaQueryWrapper<Workresource>()
                            .eq(Workresource::getProductLineId, t.getMoctyudf05())
                            .eq(Workresource::getResourceId, t.getResourceGroupIdIsF()));
                    if(workresourceList.size() > 0) t.setBeat(workresourceList.get(0).getBeat() == null ? null : workresourceList.get(0).getBeat().toString());
                }
            }
        }
        return Result.success(list);
    }

    private List<String> getDates(String start, String end) {
        List<String> dateList = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDate startDate = LocalDate.parse(start, formatter);
        LocalDate endDate = LocalDate.parse(end, formatter);
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            dateList.add(currentDate.format(formatter));
            currentDate = currentDate.plusDays(1);
        }
        return dateList;
    }

    @ApiOperation("设备|生产线负荷情况 具体当日的表格")
    @PostMapping("deviceLoadDetailPerDay")
    public Result<List<MoctyPlus>> deviceLoadDetailPerDay(@RequestBody DeviceLoadDetailPerDayDto dto) {
        List<String> statusList = new ArrayList<>();
        statusList.add(MOCStatusEnum.DaiPaiJi.getValue());
        statusList.add(MOCStatusEnum.DaiShouJian.getValue());  statusList.add(MOCStatusEnum.ShouJianZhong.getValue());
        statusList.add(MOCStatusEnum.DaiJinZhan.getValue());  statusList.add(MOCStatusEnum.ShengChanZhong.getValue());
        statusList.add(MOCStatusEnum.DaiKaiJi.getValue());  statusList.add(MOCStatusEnum.ZanTing.getValue());
        statusList.add(MOCStatusEnum.DaiShangLiaoQueRen.getValue()); statusList.add(MOCStatusEnum.DaiMuJuQueRen.getValue());
        List<MoctyPlus> moctyPlusList = moctyMapper.moctyOnQueueListByMocStatusAndDateAndMacId
                (statusList, dto.getDate(), dto.getDate(), dto.getResourceGroupIdIsF());
        for(MoctyPlus moctyPlus : moctyPlusList) {
            Workresource workresource = workresourceService.getOne(new LambdaQueryWrapper<Workresource>()
                    .eq(Workresource::getProductLineId, moctyPlus.getUdf05())
                    .eq(Workresource::getResourceId, dto.getResourceGroupIdIsF()));
            if(workresource == null || workresource.getBeat() == null || workresource.getBeat().equals(0D)) continue;
            moctyPlus.setBeat(workresource.getBeat().toString());
            moctyPlus.setLoadTime(new BigDecimal(moctyPlus.getTy004() * workresource.getBeat() / 3600).setScale(2, RoundingMode.HALF_UP));
        }
        return Result.success(moctyPlusList);
    }

    @ApiOperation("设备|生产线负荷情况")
    @PostMapping("deviceLoadStatus")
    public Result<List<ResourceLoadListVo>> deviceLoadStatus(@RequestBody DeviceLoadStatusDto dto) {
        if(StringUtils.isEmpty(dto.getLeftTime()) || StringUtils.isEmpty(dto.getRightTime())) {
            return Result.error("日期区间不能为空");
        }
        List<String> statusList = new ArrayList<>();
        statusList.add(MOCStatusEnum.DaiPaiJi.getValue());
        statusList.add(MOCStatusEnum.DaiShouJian.getValue());  statusList.add(MOCStatusEnum.ShouJianZhong.getValue());
        statusList.add(MOCStatusEnum.DaiJinZhan.getValue());  statusList.add(MOCStatusEnum.ShengChanZhong.getValue());
        statusList.add(MOCStatusEnum.DaiKaiJi.getValue());  statusList.add(MOCStatusEnum.ZanTing.getValue());
        statusList.add(MOCStatusEnum.DaiShangLiaoQueRen.getValue()); statusList.add(MOCStatusEnum.DaiMuJuQueRen.getValue());
        List<MoctyPlus> moctyList = moctyMapper.moctyOnQueueListByMocStatusAndDate
                (statusList, dto.getLeftTime(), dto.getRightTime());
        Set<String> macSet = new HashSet<>();
        Map<String, List<MoctyPlus>> macDateNumMap = new HashMap<>();
        for(MoctyPlus t : moctyList) {
            macSet.add(t.getTy009());
            List<MoctyPlus> plusList = macDateNumMap.get(t.getTy003().trim() + ";" + t.getTy009().trim());
            if(plusList == null) plusList = new ArrayList<>();
            plusList.add(t);
            macDateNumMap.put(t.getTy003().trim() + ";" + t.getTy009().trim(), plusList);
        }
        List<String> macList = new ArrayList<>();
        for(String t : macSet) macList.add(t);
        List<ResourceLoadListVo> list = resourceMapper.deviceLoadStatusList(dto, macList);
        List<Cmsmd> cmsmdList = cmsmdService.list();
        Map<String, String> cmsmdMap = new HashMap<>();
        for(Cmsmd cmsmd : cmsmdList) {
            cmsmdMap.put(cmsmd.getMd001().trim(), cmsmd.getMd002().trim());
        }
        List<String> dates = getDates(dto.getLeftTime(), dto.getRightTime());
        for(ResourceLoadListVo t : list) {   // 设备
            List<LoadDateVo> p = new ArrayList<>();
            // 日期区间中有的有哪些
            for(String date : dates) {   // 日期
                List<MoctyPlus> moctyPlusList = macDateNumMap.get(date + ";" + t.getResourceGroupIdIsF().toString());
                if(moctyPlusList == null || moctyPlusList.size() == 0) continue;
                BigDecimal sum = new BigDecimal(0D);
                for(MoctyPlus moctyPlus : moctyPlusList) {
                    Workresource workresource = workresourceService.getOne(new LambdaQueryWrapper<Workresource>()
                            .eq(Workresource::getProductLineId, moctyPlus.getUdf05())
                            .eq(Workresource::getResourceId, t.getResourceGroupIdIsF()));
                    if(workresource == null || workresource.getBeat() == null || workresource.getBeat().equals(0D)) continue;
                    sum = sum.add(new BigDecimal(moctyPlus.getTy004() * workresource.getBeat() / 3600));
                }
                sum = sum.setScale(2, RoundingMode.HALF_UP);
                p.add(new LoadDateVo(date, sum));
            }
            t.setLoadDates(p);
        }
        return Result.success(list);
    }

    @ApiOperation("设备|生产线列表")
    @PostMapping("deviceProductLineList222")
    public Result<List<DeviceProductLineListVo>> deviceProductLineList222() {
        List<DeviceProductLineListVo> res = resourceMapper.deviceProductLineList2();
        return Result.success(res);
    }

//    @ApiOperation("生产线组列表")
//    @PostMapping("addProductLine")
//    public Result addProductLine(@RequestBody AddProductLineDto dto) {
//        Resource resource = new Resource();
//        BeanUtils.copyPropertiesIgnoreCase(dto, resource);
//        resource.setResourceType(2);
//        resource.setResourceid(null);
//        boolean b = resourceService.save(resource);
//        if(b) return Result.success("添加生产线成功");
//        else return Result.success("添加生产线失败");
//    }

}
